

#include "NTPTime.h"
#include <WiFi.h>
#include <Time.h>
#include <NTPClient.h>
#include <TimeLib.h>

#include <Preferences.h>
#include <ESP32Time.h>
#include <Arduino.h>
#include "utils.h"
#include "global.h"

RTC_DATA_ATTR long RTC_TIME = 0;
RTC_DATA_ATTR long RTC_COUNTER = 0;


// #include <RTClib.h>

// // 定义星期名称
// String weekDays[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// // 定义月份名称
// String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

// 定义星期名称
String weekDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// 定义月份名称
String months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

const char *ntpServer = "pool.ntp.org"; // NTP服务器地址
const long gmtOffset_sec = 8 * 3600;//    // GMT偏移量（秒），例如中国是东八区，即8小时
const int daylightOffset_sec = 0;       // 夏令时偏移量（秒），中国不使用夏令时，所以是0

WiFiUDP ntpUDP;
 //NTPClient timeClient(ntpUDP, "pool.ntp.org",gmtOffset_sec);
NTPClient timeClient(ntpUDP, "pool.ntp.org");

ESP32Time rtc;

bool isSetRtcTime()
{
  return true;
}

int updateTimeCount = 0;

int setRTCNTPTime(){
   RTC_COUNTER++;
   if(!isWiFiConnected())
   {
     if(RTC_TIME==0){
      return -1;
     }
     rtc.setTime(RTC_TIME);
    return 0;
   }
  if(RTC_COUNTER%10!=0&&RTC_TIME!=0){
    rtc.setTime(RTC_TIME);
    return 0;
  }
  setNTPTime();
}
int setNTPTime()
{
  

  Preferences preferences;
  preferences.begin("my-app", false);
  String ssid =getSsid();
  String password = getPassword();

  // WiFi.begin(ssid.c_str(), password.c_str());
  // while (WiFi.status() != WL_CONNECTED)
  // {
  //   delay(500);
  //   Serial.print(".");
  // }

  timeClient.begin();
  timeClient.setTimeOffset(28800);
  timeClient.update();
  Serial.println("格式化时间：");
  Serial.println(timeClient.getFormattedTime());
  long s = timeClient.getEpochTime();
  while (s < 10000000)
  {
    delay(1000);
    timeClient.update();
    delay(500);
    Serial.println("格式化时间：");
    Serial.println(timeClient.getFormattedTime());
    s = timeClient.getEpochTime();
    updateTimeCount++;
    if (updateTimeCount >= 10)
    {
      printStr("获取NTC时间失败，设备重启");
      return -2;
    }
  }
  Serial.print("RTCTime 设置成功,时间戳");
  Serial.println(s);
  RTC_TIME = s;
  rtc.setTime(s);
  return 0;
}

ESP32Time getRtcTime()
{

   
  return rtc;
}

long getEpoch(){
  return rtc.getEpoch()-8*3600;
}

unsigned long computeIntervalCurrent(unsigned long epoch)
{
  return rtc.getEpoch() - epoch;
}

void getDateTime()
{
  // 请求网络时间
  timeClient.update();

  unsigned long epochTime = timeClient.getEpochTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);

  // 解析网络时间
  String formattedTime = timeClient.getFormattedTime();
  Serial.print("Formatted Time: ");
  Serial.println(formattedTime);

  int currentHour = timeClient.getHours();
  Serial.print("Hour: ");
  Serial.println(currentHour);

  int currentMinute = timeClient.getMinutes();
  Serial.print("Minutes: ");
  Serial.println(currentMinute);

  int currentSecond = timeClient.getSeconds();
  Serial.print("Seconds: ");
  Serial.println(currentSecond);

  String weekDay = weekDays[timeClient.getDay()];
  Serial.print("Week Day: ");
  Serial.println(weekDay);

  // Get a time structure
  struct tm *ptm = gmtime((time_t *)&epochTime);

  int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon + 1;
  Serial.print("Month: ");
  Serial.println(currentMonth);

  String currentMonthName = months[currentMonth - 1];
  Serial.print("Month name: ");
  Serial.println(currentMonthName);

  int currentYear = ptm->tm_year + 1900;
  Serial.print("Year: ");
  Serial.println(currentYear);

  // Print complete date:
  String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
  Serial.print("Current date: ");
  Serial.println(currentDate);

  Serial.println("");
}

// 辅助函数，用于将两个字符转换为整数
int charPairToInt(char a, char b)
{
  return (a - '0') * 10 + (b - '0');
}

// 将时间字符串"HH:MM:SS"转换为秒数
unsigned long timeStringToSeconds(const char *timeStr)
{
  // 假设时间字符串的格式总是正确的，并且长度为8（包括'\0'）
  char hoursStr[3] = {timeStr[0], timeStr[1], '\0'};   // 提取小时部分
  char minutesStr[3] = {timeStr[3], timeStr[4], '\0'}; // 提取分钟部分
  char secondsStr[3] = {timeStr[6], timeStr[7], '\0'}; // 提取秒部分

  int hours = charPairToInt(hoursStr[0], hoursStr[1]);
  int minutes = charPairToInt(minutesStr[0], minutesStr[1]);
  int seconds = charPairToInt(secondsStr[0], secondsStr[1]);

  // 计算总秒数
  unsigned long totalSeconds = hours * 3600 + minutes * 60 + seconds;

  return totalSeconds;
}

unsigned long dhmString2Sencod(String timeStr)
{
  // 查找第一个冒号的位置
  int firstColonIndex = timeStr.indexOf(':');
  if (firstColonIndex < 0)
  {
    return timeStr.toInt() * 60;
  }

  // 查找第二个冒号的位置
  int secondColonIndex = timeStr.indexOf(':', firstColonIndex + 1);
  if (secondColonIndex < 0)
  {
    // 提取分钟
    String hour = timeStr.substring(0, firstColonIndex);
    String minite = timeStr.substring(firstColonIndex + 1);
    return hour.toInt() * 3600 + minite.toInt() * 60;
  }
  String days = timeStr.substring(0, firstColonIndex);
  
  String hours = timeStr.substring(firstColonIndex + 1, secondColonIndex);

  String minits = timeStr.substring(secondColonIndex + 1);
  return days.toInt() * 24 * 3600  +hours.toInt() * 3600 + minits.toInt() * 60;
}


//可以计算hh:mm HH:MM:SS  SS三种
unsigned long hmsString2Sencod(String hms)
{

  // 创建一个String对象，包含时间字符串
  String timeStr = hms;

  // 查找第一个冒号的位置
  int firstColonIndex = timeStr.indexOf(':');
  if (firstColonIndex < 0)
  {
    return hms.toInt();
  }
  // 查找第二个冒号的位置
  int secondColonIndex = timeStr.indexOf(':', firstColonIndex + 1);
  if (secondColonIndex < 0)
  {
    // 提取分钟
    String minite = timeStr.substring(0, firstColonIndex);
    String second = timeStr.substring(firstColonIndex + 1);
    return minite.toInt() * 60 + second.toInt();
  }
  String hours = timeStr.substring(0, firstColonIndex);
  // 提取分钟
  String minutes = timeStr.substring(firstColonIndex + 1, secondColonIndex);
  // 提取秒
  String seconds = timeStr.substring(secondColonIndex + 1);

  return hours.toInt() * 3600 + minutes.toInt() * 60 + seconds.toInt();
}

bool isDayTime()
{
  String startTime = "6:00";
  String endTime = "18:00";
  TypeConfig *tc = getGlobalLocalConfig()->getTypeConfig();
  if (tc != nullptr)
  {
    if (!isStringEmpty(tc->getStartTime()))
    {
      startTime = tc->getStartTime();
    }
    if (!isStringEmpty(tc->getEndTime()))
    {
      endTime = tc->getEndTime();
    }
  }

  String ampm =   getRtcTime().getAmPm();
  int hour = getRtcTime().getHour(true);
  int minite = getRtcTime().getMinute();

  // if(ampm.equals("PM")){
  //   if(hour>1&&hour<12)
  //    hour+=12;
  // }

 // printStr("hour",hour);
 // printStr("minite",minite);
  //printStr("ampm",ampm);

  int rtcSecond = hour*3600+minite*60;
  int startSecond = hmsString2Sencod(startTime);
  int endSecond = hmsString2Sencod(endTime);
 // printStr("rtcSecond",rtcSecond);

  if(rtcSecond>=startSecond&&rtcSecond<=endSecond){
    return true;
  }
  return false;
}

time_t stringToTimestamp(const char *str)
{
  struct tm tm;

  strptime(str, "%Y-%m-%d %H:%M:%S", &tm); // 根据你的时间字符串格式调整此格式
  time_t timestamp = mktime(&tm);
  return timestamp;
}

// void showDate(const char* txt, const DateTime& dt) {
//     Serial.print(txt);
//     Serial.print(' ');
//     Serial.print(dt.year(), DEC);
//     Serial.print('/');
//     Serial.print(dt.month(), DEC);
//     Serial.print('/');
//     Serial.print(dt.day(), DEC);
//     Serial.print(' ');
//     Serial.print(dt.hour(), DEC);
//     Serial.print(':');
//     Serial.print(dt.minute(), DEC);
//     Serial.print(':');
//     Serial.print(dt.second(), DEC);

//     Serial.print(" = ");
//     Serial.print(dt.unixtime());
//     Serial.print("s / ");
//     Serial.print(dt.unixtime() / 86400L);
//     Serial.print("d since 1970");

//     Serial.println();
// }

// void showTimeSpan(const char* txt, const TimeSpan& ts) {
//     Serial.print(txt);
//     Serial.print(" ");
//     Serial.print(ts.days(), DEC);
//     Serial.print(" days ");
//     Serial.print(ts.hours(), DEC);
//     Serial.print(" hours ");
//     Serial.print(ts.minutes(), DEC);
//     Serial.print(" minutes ");
//     Serial.print(ts.seconds(), DEC);
//     Serial.print(" seconds (");
//     Serial.print(ts.totalseconds(), DEC);
//     Serial.print(" total seconds)");
//     Serial.println();
// }

// void testTime(){
//         DateTime dt0 (0, 1, 1, 0, 0, 0);
//     showDate("dt0", dt0);

//     DateTime dt1 (1, 1, 1, 0, 0, 0);
//     showDate("dt1", dt1);

//     DateTime dt2 (2009, 1, 1, 0, 0, 0);
//     showDate("dt2", dt2);

//     DateTime dt3 (2009, 1, 2, 0, 0, 0);
//     showDate("dt3", dt3);

//     DateTime dt4 (2009, 1, 27, 0, 0, 0);
//     showDate("dt4", dt4);

//     DateTime dt5 (2009, 2, 27, 0, 0, 0);
//     showDate("dt5", dt5);

//     DateTime dt6 (2009, 12, 27, 0, 0, 0);
//     showDate("dt6", dt6);

//     DateTime dt7 (dt6.unixtime() + 3600); // One hour later.
//     showDate("dt7", dt7);

//     DateTime dt75 = dt6 + TimeSpan(0, 1, 0, 0); // One hour later with TimeSpan addition.
//     showDate("dt7.5", dt75);

//     DateTime dt8 (dt6.unixtime() + 86400L); // One day later.
//     showDate("dt8", dt8);

//     DateTime dt85 = dt6 + TimeSpan(1, 0, 0, 0); // One day later with TimeSpan addition.
//     showDate("dt8.5", dt85);

//     DateTime dt9 (dt6.unixtime() + 7 * 86400L); // One week later.
//     showDate("dt9", dt9);

//     DateTime dt95 = dt6 + TimeSpan(7, 0, 0, 0); // One week later with TimeSpan addition.
//     showDate("dt9.5", dt95);

//     DateTime dt10 = dt6 + TimeSpan(0, 0, 42, 42); // Fourty two minutes and fourty two seconds later.
//     showDate("dt10", dt10);

//     DateTime dt11 = dt6 - TimeSpan(7, 0, 0, 0);  // One week ago.
//     showDate("dt11", dt11);

//     TimeSpan ts1 = dt6 - dt5;
//     showTimeSpan("dt6-dt5", ts1);

//     TimeSpan ts2 = dt10 - dt6;
//     showTimeSpan("dt10-dt6", ts2);
// }
